﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Shell;

namespace Hong.Pan.UI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string cachePath = string.Empty;
        public MainWindow()
        {
            InitializeComponent();
            cachePath = System.Environment.CurrentDirectory + "/Cache";

            ShowDirectory();
        }

        /// <summary>
        /// 显示目录
        /// </summary>
        public async void ShowDirectory(PanFileInfo? panFile = null)
        {
            IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
            List<PanFileInfo>? list = null;
            if (panFile != null)
            {
                list = await pan.Read(panFile);
            }
            else
            {
                list = await pan.Read(panPath.Text);
            }
            if (list != null)
            {
                foreach (var item in list)
                {
                    item.background = new SolidColorBrush(Color.FromArgb(0, 0, 0, 0));

                    FileInfo fileInfo = new FileInfo(cachePath + item.path);
                    if (item.isdir == false && fileInfo.Exists)
                    {
                        item.loaded = true;
                        item.loadsize = (int)(750.0 * fileInfo.Length / item.size);
                        item.background = new SolidColorBrush(Color.FromArgb(200, 0x28, 0xa7, 0x45));
                    }
                }
                fileList.ItemsSource = list;
                //判断是否加载过盘信息
                if (panInfo.Text == string.Empty)
                {
                    JsonNode? jn = await pan.Info();
                    if (jn != null)
                    {
                        panInfo.Text = jn["baidu_name"]?.ToString();
                    }
                    jn = await pan.quota();
                    if (jn != null)
                    {
                        string tip = string.Empty;
                        long val = (long)jn["total"];
                        if (val > 1024 * 1024 * 1024)
                        {
                            tip = string.Format("{0:F2}G/{1:F2}G", (long)jn["used"] / (1024 * 1024 * 1024), val / (1024 * 1024 * 1024));
                            panInfo.ToolTip = tip;
                        }
                        //Debug.WriteLine(jn.ToString());
                    }
                }
            }
            else
            {
                LoginBaidu login = new();
                login.Show();
                Close();
            }
        }

        /// <summary>
        /// 点击文件夹
        /// </summary>
        void ListBoxDoubleClick(object sender, RoutedEventArgs e)
        {
            //Debug.WriteLine(fileList.SelectedItem);
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null)
            {
                if (pf.isdir)
                {
                    panPath.Text = pf.path;
                    ShowDirectory(pf);
                }
                else
                {
                    string localpath = cachePath + panPath.Text;
                    if (!Directory.Exists(localpath))
                    {
                        Directory.CreateDirectory(localpath);
                    }
                    if (File.Exists(localpath + "/" + pf.filename))
                    {
                        OpenFile(localpath + "/" + pf.filename);
                        return;
                    }

                    pf.loaded = true;
                    pf.loadsize = 0;
                    pf.background = new SolidColorBrush(Color.FromArgb(200, 0x28, 0xa7, 0x45));
                    fileList.Items.Refresh();

                    Task.Run(async () =>
                    {
                        IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
                        int ret = await pan.Read(pf, localpath, (long loadedSize) =>
                        {
                            Debug.WriteLine($"loadedSize:{loadedSize}");
                            pf.loadsize = (int)(750.0 * loadedSize / pf.size);
                            Dispatcher.BeginInvoke(UpdateItem);
                            //fileList.Items.Refresh();
                        });
                        if (ret == 0)
                        {
                            pf.loadsize = 750;
                            await Dispatcher.BeginInvoke(UpdateItem);
                            OpenFile(localpath + "/" + pf.filename);
                        }
                    });
                }
            }
        }

        /// <summary>
        /// 更新显示元素
        /// </summary>
        private void UpdateItem()
        {
            fileList.Items.Refresh();
        }

        /// <summary>
        /// 用系统默认程序打开文件
        /// </summary>
        /// <param name="fn"></param>
        private void OpenFile(string fn)
        {
            ProcessStartInfo processStartInfo = new ProcessStartInfo(fn);
            Process process = new Process();
            process.StartInfo = processStartInfo;
            process.StartInfo.UseShellExecute = true;
            process.Start();
        }

        /// <summary>
        /// 返回上层目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (panPath.Text.Length > 1)
            {
                int pos = panPath.Text.LastIndexOf('/', panPath.Text.Length - 2);
                panPath.Text = panPath.Text.Substring(0, pos + 1);
                ShowDirectory();
            }
        }

        /// <summary>
        /// 返回上层目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Refresh_Click(object sender, RoutedEventArgs e)
        {
            fileList.SelectedItem = null;
            ShowDirectory();
        }

        /// <summary>
        /// 打开文件或者目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Open_Click(object sender, RoutedEventArgs e)
        {
            ListBoxDoubleClick(sender, e);
        }

        /// <summary>
        /// 复制文件或者目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Copy_Click(object sender, RoutedEventArgs e)
        {

        }

        /// <summary>
        /// 粘贴文件系统文件或者目录到网盘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Paste_Click(object sender, RoutedEventArgs e)
        {
            if (Clipboard.ContainsData(DataFormats.FileDrop))
            {
                var filedrop = Clipboard.GetData(DataFormats.FileDrop);
                if (filedrop != null)
                {
                    string[]? filelist = filedrop as string[];
                    if (filelist != null)
                    {
                        PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
                        string upPath = panPath.Text + "/";
                        if (pf != null && pf.isdir)
                        {
                            upPath += pf.filename + "/";
                        }

                        IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
                        foreach (var item in filelist)
                        {
                            FileInfo fileInfo = new FileInfo(item);
                            if ((File.GetAttributes(item) & FileAttributes.Directory) == FileAttributes.Directory) //目录
                            {
                                uploadDirectory(item, upPath + fileInfo.Name + "/");
                            }
                            else //文件
                            {
                                pan.Write(panPath.Text + "/" + fileInfo.Name, item);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Down_Click(object sender, RoutedEventArgs e)
        {
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null)
            {
                if (pf.isdir)
                {

                }
                else //暂时只处理下载文件
                {
                    string localpath = cachePath + panPath.Text;
                    if (!Directory.Exists(localpath))
                    {
                        Directory.CreateDirectory(localpath);
                    }
                    Task.Run(async () => { 
                        IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
                        int ret = await pan.Read(pf, localpath, (long loadedSize) => {
                            Debug.WriteLine($"loadedSize:{loadedSize}");
                            pf.loadsize = (int)(750.0 * loadedSize / pf.size);
                            Dispatcher.BeginInvoke(UpdateItem);
                            //fileList.Items.Refresh();
                        });
                        if (ret == 0)
                        {
                            pf.loadsize = 750;
                            await Dispatcher.BeginInvoke(UpdateItem);
                        }
                    });
                }
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Delete_Click(object sender, RoutedEventArgs e)
        {
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null)
            {
                if (MessageBox.Show("您确定要删除的文件？", "删除", MessageBoxButton.YesNoCancel) == MessageBoxResult.Yes)
                {
                    //空文件夹才能删除
                    //if (pf.isdir)
                    //{

                    //}
                    //else //暂时只处理删除文件
                    //{
                        IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
                        int ret = await pan.Delete(pf.path);
                        if (ret == 0)
                        {
                            fileList.SelectedItem = null;
                            ShowDirectory();
                        }
                    //}
                }
            }
        }

        /// <summary>
        /// 删除本地文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeleteFile_Click(object sender, RoutedEventArgs e)
        {
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null && pf.loaded)
            {
                if (MessageBox.Show("您确定要删除本地的文件？", "删除", MessageBoxButton.YesNoCancel) == MessageBoxResult.Yes)
                {
                    File.Delete(cachePath + panPath.Text + "/" + pf.filename);
                    pf.loaded = false;
                    pf.background = null;
                    fileList.Items.Refresh();
                }
            }
        }

        /// <summary>
        /// 播放视频
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Play_Click(object sender, RoutedEventArgs e)
        {
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null)
            {
                IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
                pan?.ReadVideo(pf);
            }
        }

        /// <summary>
        /// 菜单打开时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileList_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null)
            {
                //判断粘贴是否可用
                MenuItem? menuItem = fileMenu.Items[2] as MenuItem;
                if (menuItem != null)
                {
                    menuItem.IsEnabled = false;
                    if (panPath.Text.Length >= 5 && panPath.Text.Substring(0, 5) == "/apps") //只有指定目录可以上传
                    {
                        if (pf.filename == "我的盘" || (panPath.Text.Length >= 9 && panPath.Text.Substring(0, 9) == "/apps/我的盘"))
                        {
                            //判断剪贴板是否有内容
                            if (Clipboard.ContainsData(DataFormats.FileDrop))
                            {
                                menuItem.IsEnabled = pf.isdir;
                            }
                        }
                    }
                }
                //判断下载是否可用
                menuItem = fileMenu.Items[3] as MenuItem;
                if (menuItem != null)
                {
                    menuItem.IsEnabled = !pf.loaded;
                }
                //判断资源管理器显示是否可用
                menuItem = fileMenu.Items[4] as MenuItem;
                if (menuItem != null)
                {
                    menuItem.IsEnabled = pf.loadsize > 0;
                }
                //判断删除本地文件显示是否可用
                menuItem = fileMenu.Items[6] as MenuItem;
                if (menuItem != null)
                {
                    menuItem.IsEnabled = pf.loaded;
                }
            }
        }

        /// <summary>
        /// 在资源管理器中显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Explore_Click(object sender, RoutedEventArgs e)
        {
            PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
            if (pf != null)
            {
                string cpath = cachePath + "/" + pf.filename;
                //文件中带空格显示有问题
                cpath = "/select," + System.IO.Path.GetFullPath(cpath) + "";
                //Debug.WriteLine(cpath);
                //Process.Start("Explorer.exe", "E:\\gitee\\baidupan-wpf\\Hong.Pan.UI\\bin\\Debug\\net6.0-windows\\Cache");
                Process.Start("Explorer.exe", cpath);
            }
        }

        /// <summary>
        /// 拖放文件在组件上时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileList_DragOver(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;
            if (e.Data.GetDataPresent(DataFormats.FileDrop) && (panPath.Text.Length >= 9 && panPath.Text.Substring(0, 9) == "/apps/我的盘"))
            {
                e.Effects = DragDropEffects.Copy;
                Mouse.SetCursor(Cursors.Cross);
            }
            else
            {
                Mouse.SetCursor(Cursors.No);
            }
            e.Handled = true;
        }

        /// <summary>
        /// 拖放文件在文件放下时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void fileList_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) && (panPath.Text.Length >= 9 && panPath.Text.Substring(0, 9) == "/apps/我的盘"))
            {
                var filedrop = e.Data.GetData(DataFormats.FileDrop);
                if (filedrop != null)
                {
                    string[]? filelist = filedrop as string[];
                    if (filelist != null)
                    {
                        PanFileInfo? pf = fileList.SelectedItem as PanFileInfo;
                        string upPath = panPath.Text + "/";
                        if (pf != null && pf.isdir)
                        {
                            upPath += pf.filename + "/";
                        }
                        IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
                        foreach (var item in filelist)
                        {
                            FileInfo fileInfo = new FileInfo(item);
                            if ((File.GetAttributes(item) & FileAttributes.Directory) == FileAttributes.Directory) //目录
                            {
                                uploadDirectory(item, upPath + fileInfo.Name + "/");
                            }
                            else //文件
                            {
                                pan.Write(upPath + fileInfo.Name, item);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 上传目录
        /// </summary>
        /// <param name="path"></param>
        private void uploadDirectory(string path, string uploadPath)
        {
            IPan? pan = ((App)Application.Current).ServiceProvider.GetService<Baidu>();
            string[] files = Directory.GetFiles(path);
            foreach (string file in files)
            {
                FileInfo fileInfo = new FileInfo(file);
                if ((File.GetAttributes(file) & FileAttributes.Directory) == FileAttributes.Directory) //目录
                {
                    uploadDirectory(file, uploadPath + fileInfo.Name + "/");
                }
                else //文件
                {
                    pan.Write(uploadPath + fileInfo.Name, file);
                }
            }
        }
    }
}
